package com.ruoyi.member.service.impl;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.RedisKeyEnum;
import com.ruoyi.member.utils.JwtUtil;
import com.ruoyi.member.entity.domain.MobileUser;
import com.ruoyi.member.entity.req.WxMiniLoginReq;
import com.ruoyi.member.entity.resp.WxMiniLoginResp;
import com.ruoyi.common.vo.AppUser;
import com.ruoyi.member.mapper.MobileUserMapper;
import com.ruoyi.member.service.WeChatMiniService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 微信小程序服务实现类
 */
@Service
@Slf4j
public class WeChatMiniServiceImpl implements WeChatMiniService {

    @Autowired
    private WeChatMiniHttp weChatMiniHttp;
    @Autowired
    private MobileUserMapper mobileUserMapper;
    @Autowired
    private RedisCache redisCache;

    @Value("${wechat.jwt.user-secret-key}")
    private String userSecretKey;
    @Value("${wechat.jwt.user-ttl-day}")
    private Integer userTtlDay;


    @Override
    public String getWxAccessToken() {
        return "";
    }

    /**
     * 小程序登录
     */
    @Override
    public R<WxMiniLoginResp> login(WxMiniLoginReq req) {
        String code = req.getCode();

        log.info("微信小程序登录：{}", code);
        if (StrUtil.isBlank(code)) {
            return R.fail("code不能为空");
        }

        JSONObject jsonObject = weChatMiniHttp.login(req);
/*        JSONObject jsonObject = new JSONObject();
        jsonObject.put("openid", "o_j5g5XwzY5ZwzY5ZwzY5ZwzY5ZwzY");
        jsonObject.put("session_key", "session_key");
        jsonObject.put("unionid", "unionid");
        jsonObject.put("errcode", 0);*/

        if (ObjUtil.isNotEmpty(jsonObject) && jsonObject.getIntValue("errcode") == 0 && StrUtil.isNotBlank(jsonObject.getString("openid"))) {
            String openid = jsonObject.getString("openid");
            String sessionKey = jsonObject.getString("session_key");
            String unionid = jsonObject.getString("unionid");

            //如果是新用户 则新增
            LambdaQueryWrapper<MobileUser> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(MobileUser::getOpenId, openid);
            queryWrapper.last("limit 1");
            MobileUser mobileUser = mobileUserMapper.selectOne(queryWrapper);
            if (ObjUtil.isEmpty(mobileUser)) {
                mobileUser = new MobileUser();
                mobileUser.setOpenId(openid);
                mobileUser.setUnionId(unionid);
                mobileUser.setCreateTime(new Date());
                mobileUserMapper.insert(mobileUser);
            } else {
                mobileUser.setMiniLastLoginTime(new Date());
                mobileUserMapper.updateById(mobileUser);
            }

            //为微信用户生成jwt令牌
            Map<String, Object> claims = new HashMap<>();
            claims.put("user_id", mobileUser.getId());
            claims.put("session_key", sessionKey);
            String token = JwtUtil.createJWT(userSecretKey, userTtlDay + 1, claims);

            //缓存登录状态
            AppUser user = new AppUser();
            user.setUserId(mobileUser.getId());
            user.setPhone(mobileUser.getPhoneNumber());
            user.setName(mobileUser.getName());
            user.setUnionId(mobileUser.getUnionId());
            user.setOpenId(openid);
            user.setSessionKey(sessionKey);

            redisCache.setCacheObject(RedisKeyEnum.LOGIN_TOKEN.getPrefix() + mobileUser.getId(),
                    user, userTtlDay, RedisKeyEnum.LOGIN_TOKEN.getTimeUnit());

            WxMiniLoginResp resp = new WxMiniLoginResp();
            resp.setToken(token);

            //记录登录日志

            return R.ok(resp);
        } else {
            return R.fail("登录失败");
        }
    }

}
